<?php


namespace IDock\Insurance\ACIC;

use IDock\Http\Response;
use IDock\IDock\IDockInterface;
use IDock\Insurance\ACIC\Request\EPolicyDownloadRequest;
use IDock\Insurance\ACIC\Request\NonCar\NonCarCollectionRequest;
use IDock\Insurance\ACIC\Request\NonCar\NonCarEPolicyDownRequest;
use IDock\Insurance\ACIC\Request\NonCar\NonCarInquiryInfoRequest;
use IDock\Insurance\ACIC\Request\NonCar\NonCarInquiryNoPreBuildRequest;
use IDock\Insurance\ACIC\Request\NonCar\NonCarInquiryRequest;
use IDock\Insurance\ACIC\Request\NonCar\NonCarRegisterRequest;
use IDock\Insurance\ACIC\Request\PolicyInfoRequest;
use IDock\Insurance\ACIC\Request\PolicyPaymentRequest;
use IDock\Insurance\ACIC\Request\PremiumInquiryRequest;
use IDock\Insurance\ACIC\Request\ProposalRecallRequest;
use IDock\Insurance\ACIC\Request\ProposalStatusRequest;
use IDock\Insurance\ACIC\Request\RenewalInquiryRequest;
use IDock\Insurance\ACIC\Request\UnderwritingRecallRequest;
use IDock\Insurance\ACIC\Request\UnderwritingRequest;
use IDock\Insurance\ACIC\Request\UploadFileRequest;
use IDock\Insurance\ACIC\Request\UploadResultQueryRequest;
use IDock\Insurance\ACIC\Request\ValidateCarRequest;
use IDock\Insurance\ACIC\Request\VehicleModelRequest;
use IDock\Insurance\ACIC\Response\EPolicyDownloadResponse;
use IDock\Insurance\ACIC\Response\NonCar\NonCarCollectionResponse;
use IDock\Insurance\ACIC\Response\NonCar\NonCarEPolicyDownResponse;
use IDock\Insurance\ACIC\Response\NonCar\NonCarInquiryNoPreBuildResponse;
use IDock\Insurance\ACIC\Response\NonCar\NonCarInquiryResponse;
use IDock\Insurance\ACIC\Response\NonCar\NonCarProductListResponse;
use IDock\Insurance\ACIC\Response\PolicyInfoResponse;
use IDock\Insurance\ACIC\Response\PolicyPaymentResponse;
use IDock\Insurance\ACIC\Response\PremiumInquiryResponse;
use IDock\Insurance\ACIC\Response\ProposalRecallResponse;
use IDock\Insurance\ACIC\Response\ProposalStatusResponse;
use IDock\Insurance\ACIC\Response\RenewalInquiryResponse;
use IDock\Insurance\ACIC\Response\UnderwritingRecallResponse;
use IDock\Insurance\ACIC\Response\UnderwritingResponse;
use IDock\Insurance\ACIC\Response\UploadFileResponse;
use IDock\Insurance\ACIC\Response\UploadResultQueryResponse;
use IDock\Insurance\ACIC\Response\ValidateCarResponse;
use IDock\Insurance\ACIC\Response\VehicleActualValueResponse;
use IDock\Insurance\ACIC\Response\VehicleModelResponse;
use IDock\Printer\NonCar\NonCarInquiryPrinter;
use IDock\Printer\NonCar\NonCarInquirySinglePrinter;
use IDock\Printer\PremiumUnderwritingPrinter;
use IDock\Visitor\EPolicyDownloadVisitor;
use IDock\Visitor\NonCar\NonCarInquiryVisitor;
use IDock\Visitor\NonCar\NonCarProductListVisitor;
use IDock\Visitor\NonCar\NonCarProductVisitor;
use IDock\Visitor\PolicyInfoVisitor;
use IDock\Visitor\PolicyPaymentVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use IDock\Visitor\ProposalRecallVisitor;
use IDock\Visitor\ProposalStatusVisitor;
use IDock\Visitor\RenewalInquiryVisitor;
use IDock\Visitor\UnderwritingRecallVisitor;
use IDock\Visitor\UploadFileVisitor;
use IDock\Visitor\ValidateCarVisitor;
use IDock\Visitor\VehicleActualValueVisitor;
use IDock\Visitor\VehicleModelVisitor;

class ACICConstruct extends Builder implements IDockInterface
{
    public $config = [];

    public function __construct($config)
    {
        $this->config = $config;

        //车险配置
        $this->EChannelId = $config['EChannelId'] ?? '';
        $this->secretKey = $config['secretKey'] ?? '';
        $this->PCPayUrl = $config['PCPayUrl'] ?? '';
        $this->WAPPayUrl = $config['WAPPayUrl'] ?? '';
        $this->ip = $config['ip'] ?? '';
        //非车配置
        $this->NCGateway = $config['NCGateway'] ?? '';
        $this->NCEChannelId = $config['NCEChannelId'] ?? '';
        $this->NCSecretKey = $config['NCSecretKey'] ?? '';
    }

    /**
     * 续保查询
     * @param RenewalInquiryVisitor $renewalInquiryVisitor
     * @return RenewalInquiryResponse
     */
    public function renewalInquiry(RenewalInquiryVisitor $renewalInquiryVisitor): RenewalInquiryResponse
    {
        $request = new RenewalInquiryRequest();
        $request->setVisitor($renewalInquiryVisitor);

        /*** @var RenewalInquiryResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 车型查询
     * @param VehicleModelVisitor $vehicleModelVisitor
     * @return VehicleModelResponse
     */
    public function vehicleModel(VehicleModelVisitor $vehicleModelVisitor): VehicleModelResponse
    {
        $request = new VehicleModelRequest();
        $request->setVisitor($vehicleModelVisitor);

        /*** @var VehicleModelResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 车辆实际价格
     * @param VehicleActualValueVisitor $vehicleActualValueVisitor
     * @return VehicleActualValueResponse
     */
    public function vehicleActualValue(VehicleActualValueVisitor $vehicleActualValueVisitor): VehicleActualValueResponse
    {
        $response = new VehicleActualValueResponse();
        $response->setCode(200);
        $response->setVisitor($vehicleActualValueVisitor);
        $response->printerInit();
        return $response;
    }

    /**
     * 询价前置
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return void
     */
    public function preInquiry(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }

    public function validateCar(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }

    /**
     * 询价
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return Response
     */
    public function premiumInquiry(PremiumInquiryVisitor $premiumInquiryVisitor): Response
    {
        $request = new PremiumInquiryRequest;
        $request->setVisitor($premiumInquiryVisitor);

        //车险询价
        /*** @var PremiumInquiryResponse $mainResponse */
        $mainResponse = $this->execute($request);

        if (!$mainResponse->isSuccess() or !$mainResponse->printer->success) {
            return $mainResponse;
        }

        //非车数据回填
        if ($premiumInquiryVisitor->getNonCarInquiryVisitor()->getNonCarList()) {
            $nonCarInquiryPrinter = new NonCarInquiryPrinter();
            $totalPremium = 0;
            foreach ($premiumInquiryVisitor->getNonCarInquiryVisitor()->getNonCarList() as $item) {
                /*** @var $item NonCarProductVisitor */
                $single = new NonCarInquirySinglePrinter();
                $single->premium = $item->premium;
                $single->planCode = $item->planCode;
                $single->productCode = $item->productCode;
                $single->statusCode = 'success';

                $totalPremium += $single->premium * $item->insuredNum;
                $nonCarInquiryPrinter->noCarInquirySingleAppend($single);
            }
            $nonCarInquiryPrinter->totalPremium = $totalPremium;

            $mainResponse->printer->nonCarInquiryPrinter = $nonCarInquiryPrinter;

            return $mainResponse;
        }

        return $mainResponse;
    }

    /**
     * 核保--附加非车登记
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return Response
     */
    public function underwriting(PremiumInquiryVisitor $premiumInquiryVisitor): Response
    {
        $request = new UnderwritingRequest();
        $request->setVisitor($premiumInquiryVisitor);

        /*** @var UnderwritingResponse $mainResponse */
        $mainResponse = $this->execute($request);

        if (!$mainResponse->isSuccess()) {
            return $mainResponse;
        }

        if ($premiumInquiryVisitor->getNonCarUnderwritingVisitor()->getNonCarList()) {
            //非车投保单号预生成
            //非车详细信息登记
            return $this->ACICNonCarInquiryNoPreBuild($premiumInquiryVisitor, $mainResponse);
        }

        return $mainResponse;
    }

    /**
     *  非车询价登记
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @param UnderwritingResponse $mainResponse
     * @return Response
     */
    private function ACICNonCarInquiryNoPreBuild(PremiumInquiryVisitor $premiumInquiryVisitor, UnderwritingResponse $mainResponse): Response
    {
        /*** @var PremiumUnderwritingPrinter $printer */
        $printer = $mainResponse->getPrinter();

        //非车投保单号预生成
        $request = new NonCarInquiryNoPreBuildRequest();
        $request->deptCode = $premiumInquiryVisitor->getExtInfoVisitor()->argc['DeptCode'] ?? '';

        /*** @var NonCarInquiryNoPreBuildResponse $proBuildResponse */
        $proBuildResponse = $this->execute($request);

        if (!$proBuildResponse->isSuccess()) {
            $mainResponse->setError($proBuildResponse->getError());
            return $mainResponse;
        }

        //非车详细信息登记接口
        $registerRequest = new NonCarRegisterRequest();
        $registerRequest->appNo = $proBuildResponse->inquiryNo;
        $registerRequest->beginDate = $premiumInquiryVisitor->getNonCarUnderwritingVisitor()->startData;
        $registerRequest->endDate = $premiumInquiryVisitor->getNonCarUnderwritingVisitor()->endData;
        $registerRequest->premium = array_sum(array_column($premiumInquiryVisitor->getNonCarUnderwritingVisitor()->getNonCarList(), 'premium'));
        $registerRequest->biInquiryNo = $printer->biInquiryNo;
        $registerRequest->ciInquiryNo = $printer->ciInquiryNo;
        $registerRequest->coverage($premiumInquiryVisitor->getNonCarUnderwritingVisitor());

        $registerResponse = $this->execute($registerRequest);

        if (!$registerResponse->isSuccess()) {
            $mainResponse->setError($registerResponse->getError());
            return $mainResponse;
        }

        //非车数据回填
        /*** @var NonCarInquirySinglePrinter $value */
        $nonProduct = $premiumInquiryVisitor->getNonCarUnderwritingVisitor()->getNonCarList()[0];

        $single = new NonCarInquirySinglePrinter();
        $single->productCode = $nonProduct->productCode;
        $single->planCode = $nonProduct->planCode;
        $single->inquiryNo = $proBuildResponse->inquiryNo;
        $printer->noCarUnderwritingPrinter->nonCarSingleAppend($single);

        $mainResponse->printer = $printer;

        return $mainResponse;
    }

    /**
     * 支付
     * @param PolicyPaymentVisitor $paymentVisitor
     * @return PolicyPaymentResponse
     */
    public function policyPayment(PolicyPaymentVisitor $paymentVisitor): PolicyPaymentResponse
    {
        $request = new PolicyPaymentRequest();
        $request->setVisitor($paymentVisitor);

        /*** @var PolicyPaymentResponse $response */
        $response = $this->payment($request);
        return $response;
    }

    /**
     * 文件上传
     * @param UploadFileVisitor $uploadFileVisitor
     * @return UploadFileResponse
     */
    public function uploadFile(UploadFileVisitor $uploadFileVisitor): UploadFileResponse
    {
        $request = new UploadFileRequest();
        $request->setVisitor($uploadFileVisitor);
        /*** @var UploadFileResponse $response */

        $response = $this->execute($request);

        if (!$response->isSuccess()) {
            return $response;
        }

        $request = new UploadResultQueryRequest();

        if ($uploadFileVisitor->biInquiryNo) {
            $request->setAppNo($uploadFileVisitor->biInquiryNo);
        } elseif ($uploadFileVisitor->ciInquiryNo) {
            $request->setAppNo($uploadFileVisitor->ciInquiryNo);
        } else {
            $request->setAppNo($uploadFileVisitor->inquiryNo);
        }
        $time = 0;

        while (true) {
            sleep(10);

            /*** @var UploadResultQueryResponse $responseT */
            $responseT = $this->execute($request);

            if (!$responseT->isSuccess()) {
                $response->setError($responseT->getError());
            }

            $status = $responseT->getStatus();

            if (!strlen($status) or $time >= 20) {
                $response->setError('文件上传失败，请重试');
                return $response;
            }
            if ($status == 1) {
                return $response;
            }
            $time += 1;
        }
    }

    /**
     * 投保单状态查询
     * @param ProposalStatusVisitor $proposalStatusVisitor
     * @return ProposalStatusResponse
     */
    public function proposalStatus(ProposalStatusVisitor $proposalStatusVisitor): ProposalStatusResponse
    {
        $request = new ProposalStatusRequest();
        $request->setVisitor($proposalStatusVisitor);

        /*** @var ProposalStatusResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 撤单接口
     * @param ProposalRecallVisitor $revokeVisitor
     * @return ProposalRecallResponse
     */
    public function proposalRecall(ProposalRecallVisitor $revokeVisitor): ProposalRecallResponse
    {
        $request = new ProposalRecallRequest();
        $request->setVisitor($revokeVisitor);

        /*** @var ProposalRecallResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 电子保单下载
     * @param EPolicyDownloadVisitor $EPolicyVisitor
     * @return EPolicyDownloadResponse
     */
    public function EPolicyDownload(EPolicyDownloadVisitor $EPolicyVisitor): EPolicyDownloadResponse
    {
        $request = new EPolicyDownloadRequest();
        $request->setVisitor($EPolicyVisitor);

        /*** @var EPolicyDownloadResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 核保撤回
     * @param UnderwritingRecallVisitor $recallVisitor
     * @return mixed|void
     */
    public function underwritingRecall(UnderwritingRecallVisitor $recallVisitor): UnderwritingRecallResponse
    {
        $request = new UnderwritingRecallRequest();
        $request->setVisitor($recallVisitor);

        /*** @var UnderwritingRecallResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 保单状态查询
     * @param PolicyInfoVisitor $policyInfoVisitor
     * @return Response
     */
    public function policyInfo(PolicyInfoVisitor $policyInfoVisitor)
    {
        $request = new PolicyInfoRequest();
        $request->setVisitor($policyInfoVisitor);

        /*** @var $response PolicyInfoResponse */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 非车产品
     * @param NonCarProductListVisitor $nonCarProductListVisitor
     * @return NonCarProductListResponse
     */
    public function nonCarProductList(NonCarProductListVisitor $nonCarProductListVisitor): Response
    {
        $response = new NonCarProductListResponse();
        $response->seats = $nonCarProductListVisitor->seats;
        $response->printerInit();
        $response->setCode(200);
        return $response;
    }

    public function nonCarInquiry(NonCarInquiryVisitor $nonCarInquiryVisitor)
    {
    }

    public function nonCarUnderwriting(NonCarInquiryVisitor $inquiryPrinter)
    {
    }


    /**
     * 新车备案
     * @return void
     */
    public function newVehicleRegistration(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }

    /**
     * 验车码
     * @param ValidateCarVisitor $validateCarVisitor
     * @return ValidateCarResponse
     */
    public function validateCarCode(ValidateCarVisitor $validateCarVisitor): ValidateCarResponse
    {
        $request = new ValidateCarRequest();

        /*** @var ValidateCarResponse $response */
        $response = $this->execute($request);

        return $response;
    }

    /**
     * 非车投保接口
     * @return void
     */
    public function ACICNonCarInquiry(NonCarInquiryVisitor $nonCarInquiryVisitor): NonCarInquiryResponse
    {
        $request = new NonCarInquiryRequest();
        $request->setVisitor($nonCarInquiryVisitor);
        $request->setEChannelId($this->NCEChannelId);

        /*** @var $response NonCarInquiryResponse */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 渠道代收保单确认
     * @param NonCarCollectionRequest $carCollectionRequest
     * @return NonCarCollectionResponse
     */
    public function ACICNonCarCollection(NonCarCollectionRequest $carCollectionRequest): NonCarCollectionResponse
    {
        /*** @var $response NonCarCollectionResponse */
        $response = $this->execute($carCollectionRequest);

        return $response;
    }

    /**
     * 电子保批单地址查询接口
     * @param $policyNo
     * @return NonCarEPolicyDownResponse
     */
    public function ACICNonCarEPolicyDown($policyNo): NonCarEPolicyDownResponse
    {
        $request = new NonCarEPolicyDownRequest();
        $request->setPolicyNo($policyNo);

        /*** @var $response NonCarEPolicyDownResponse */
        $response = $this->execute($request);

        return $response;
    }

    /**
     * 非车投保单查询接口
     * @param $appNo
     * @return Response
     */
    public function nonCarInquiryInfo($appNo): Response
    {
        $request = new NonCarInquiryInfoRequest();
        $request->setAppNo($appNo);

        return $this->execute($request);
    }
}
